package org.sky.sys.service;

import org.apache.logging.log4j.Logger;
import org.sky.cache.JVMCached;
import org.sky.exception.ServiceException;
import org.sky.sys.entity.SysMenu;
import org.sky.sys.entity.SysUser;
import org.sky.sys.mapper.SysMenuMapper;
import org.sky.sys.mapper.SysUserMapper;
import org.sky.sys.util.BspUtils;
import org.sky.sys.util.MenuStru;
import org.sky.sys.util.TreeStru;
import org.sky.util.LogUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @author weifx
 * @Title: SysService
 * @ProjectName springboot-platform
 * @Description: TODO{系统业务类}
 * @date 2019/3/5 15:15
 * @Version 1.0
 */
@Service
public class SysService {
    private static Logger log = LogUtils.getLogger(SysService.class);
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    public List<MenuStru> getLeftNavMenuData(){
        List<MenuStru> menuList=null;
        if(BspUtils.isSecurityFilter()){
            log.debug("组装有权限的菜单... ...");
            menuList = getLeftNavMenuRBAC();
        }else{
            log.debug("组装无权限的菜单... ...");
            menuList = getLeftNavMenuNoRBAC();
        }
        return menuList;
    }
    /**
     * 组织有权限菜单
     * @return
     */
    private List<MenuStru> getLeftNavMenuRBAC(){
        List<MenuStru> list = new ArrayList();
        //用户具有的权限菜单
        List<SysMenu> leafMenuList = sysMenuMapper.selectLeafMenuByUserCode(BspUtils.getLoginUser().getCode());
        //权限菜单的父菜单
        List<SysMenu> parMenuList = new ArrayList();
        for(SysMenu sm:leafMenuList){
            getParentSysMenu(sm,parMenuList);
        }
        //合并权限菜单及其父菜单
        List<SysMenu> userMenuList = new ArrayList();
        userMenuList.addAll(parMenuList);
        userMenuList.addAll(leafMenuList);
        Collections.sort(userMenuList,new Comparator(){
            public int compare(Object  obj1, Object obj2 ){
                SysMenu u1 = (SysMenu)obj1;
                SysMenu u2 = (SysMenu)obj2;
                if(u1.getParentCode().compareTo(u2.getParentCode())!=0){
                    return u1.getParentCode().compareTo(u2.getParentCode());
                }else{
                    return u1.getSeq()-u2.getSeq();
                }
            }
        });
        //组织菜单数据
        for(SysMenu menu:userMenuList){
            if("root".equals(menu.getParentCode())){
                MenuStru ms = new MenuStru();
                ms.setAccordion(menu);
                if(hasChildMenu(menu.getCode())){
                    //一级树菜单
                    List<SysMenu> childlist = getChildMenu(menu.getCode(),userMenuList);
                    List<TreeStru> tslist = new ArrayList();
                    for(SysMenu cm:childlist){
                        TreeStru ts = new TreeStru();
                        ts.setId(cm.getId().toString())
                          .setCode(cm.getCode())
                          .setText(cm.getName())
                          .setIconCls(cm.getIcon())
                          .setSeq(cm.getSeq())
                          .setDefUrl(cm.getDefUrl())
                          .setData(cm);
                        recursiveRBACMenuTree(ts,userMenuList);
                        tslist.add(ts);
                    }
                    ms.setTree(tslist);
                }
                list.add(ms);
            }
        }
        return list;
    }
    /**
     * 组织无权限菜单
     * @return
     */
    private List<MenuStru> getLeftNavMenuNoRBAC(){
        List<MenuStru> list = new ArrayList();
        for(SysMenu menu:JVMCached.getMenuList()){
            if("root".equals(menu.getParentCode())){
                MenuStru ms = new MenuStru();
                ms.setAccordion(menu);
                if(hasChildMenu(menu.getCode())){
                    //一级树菜单
                    List<SysMenu> childlist = getChildMenuNoRBAC(menu.getCode());
                    List<TreeStru> tslist = new ArrayList();
                    for(SysMenu cm:childlist){
                        TreeStru ts = new TreeStru();
                        ts.setId(cm.getId().toString())
                          .setCode(cm.getCode())
                          .setText(cm.getName())
                          .setIconCls(cm.getIcon())
                          .setSeq(cm.getSeq())
                          .setDefUrl(cm.getDefUrl())
                          .setData(cm);
                        recursiveNoRBACMenuTree(ts);
                        tslist.add(ts);
                    }
                    ms.setTree(tslist);
                }
                list.add(ms);
            }
        }
        return list;
    }
    /**
     * 获取菜单的父节点,相同的父节点只添加一次
     */
    private void getParentSysMenu(SysMenu menu,List<SysMenu> parList){
        if(null==parList){
            parList=new ArrayList();
        }
        for(SysMenu sm: JVMCached.getMenuList()){
            if(menu.getParentCode().equals(sm.getCode())){
                if(!isExists(sm,parList)){
                    parList.add(sm);
                    if(!"root".equals(sm.getParentCode())){
                        getParentSysMenu(sm,parList);
                    }
                }
            }
        }
    }
    /**
     * 判断父节点是不是存在
     */
    private boolean isExists(SysMenu sm,List<SysMenu> parList){
        for(SysMenu m:parList){
            if(m.getCode().equals(sm.getCode())){
                return true;
            }
        }
        return false;
    }
    /**
     * 根据menucode获取子菜单
     * @param code
     * @return
     */
    private List<SysMenu> getChildMenu(String code,List<SysMenu> list){
        List<SysMenu> childMenulist=new ArrayList();
        for(SysMenu menu:list){
            if(code.equals(menu.getParentCode())){
                childMenulist.add(menu);
            }
        }
        return childMenulist;
    }
    /**
     * 判断菜单是否有下级
     * @param code
     * @return
     */
    private boolean hasChildMenu(String code){
        for(SysMenu menu:JVMCached.getMenuList()){
            if(code.equals(menu.getParentCode())){
                return true;
            }
        }
        return false;
    }
    /**
     * 递归组装树菜单
     * @param ts
     */
    private void recursiveNoRBACMenuTree(TreeStru ts){
        if(hasChildMenu(ts.getCode())){
            List<SysMenu> childlist = getChildMenuNoRBAC(ts.getCode());
            List<TreeStru> childmenu=new ArrayList();
            for(SysMenu sm:childlist){
                TreeStru cts= new TreeStru();
                cts.setId(sm.getId().toString())
                   .setCode(sm.getCode())
                   .setText(sm.getName())
                   .setIconCls(sm.getIcon())
                   .setSeq(sm.getSeq())
                   .setDefUrl(sm.getDefUrl())
                   .setData(sm);
                if(hasChildMenu(cts.getCode())){
                    cts.setState("closed");
                    recursiveNoRBACMenuTree(cts);
                }else{
                    cts.setState("open");
                }
                childmenu.add(cts);
            }
            ts.setState("closed");
            ts.setChildren(childmenu);
        }else{
            return;
        }
    }
    /**
     * 根据menucode获取子菜单
     * @param code
     * @return
     */
    private List<SysMenu> getChildMenuNoRBAC(String code){
        List<SysMenu> childMenulist=new ArrayList();
        for(SysMenu menu:JVMCached.getMenuList()){
            if(code.equals(menu.getParentCode())){
                childMenulist.add(menu);
            }
        }
        return childMenulist;
    }
    /**
     * 组织有权限菜单
     */
    private void recursiveRBACMenuTree(TreeStru ts,List<SysMenu> list){
        if(hasChildMenu(ts.getCode())){
            List<SysMenu> childlist = getChildMenu(ts.getCode(),list);
            List<TreeStru> childmenu=new ArrayList();
            for(SysMenu sm:childlist){
                TreeStru cts= new TreeStru();
                cts.setId(sm.getId().toString())
                   .setCode(sm.getCode())
                   .setText(sm.getName())
                   .setIconCls(sm.getIcon())
                   .setSeq(sm.getSeq())
                   .setDefUrl(sm.getDefUrl())
                   .setData(sm);
                if(hasChildMenu(cts.getCode())){
                    cts.setState("closed");
                    recursiveRBACMenuTree(cts,list);
                }else{
                    cts.setState("open");
                }
                childmenu.add(cts);
            }
            ts.setState("closed");
            ts.setChildren(childmenu);
        }else{
            return;
        }
    }

    /**
     * 密码修改
     * @param password
     * @param password1
     * @param password2
     * @throws ServiceException
     */
    public void saveUpdatePwd(String password,String password1,String password2) throws ServiceException {
        if(!password1.equals(password2)){
            throw new ServiceException("两次密码不一致");
        }
        String userCode = BspUtils.getLoginUser().getCode();
        Example example = new Example(SysUser.class);
        example.createCriteria()
                .andEqualTo("code",userCode)
                .andEqualTo("password",password);
        int count = sysUserMapper.selectCountByExample(example);
        if(count==0){
            throw new ServiceException("原密码不正确");
        }
        example.clear();
        example.createCriteria().andEqualTo("code",userCode);
        SysUser sysUser = new SysUser();
        sysUser.setPassword(password1);
        sysUserMapper.updateByExampleSelective(sysUser,example);
    }
}
